package com.colorful.insuranceproject.base;

import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.NonNull;
import android.view.View;
import android.widget.TextView;

import com.lovely3x.common.requests.Config;
import com.lovely3x.common.utils.ALog;
import com.lovely3x.common.utils.CountDownTimer;
import com.lovely3x.loginandresgiter.*;
import com.lovely3x.loginandresgiter.login.SimpleLoginActivity;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

/**
 * Created by handsome-Bob on 2017/8/17.
 */

public abstract class SimLoginNeedVerifyActivity extends SimpleLoginActivity {

    /**
     * 默认的总共倒计时时长
     */
    public static final long DEFAULT_COUNT_DOWN_TIME = 60 * 1000;
    /**
     * 默认的时间倒计时，间隔
     */
    private static final long MIN_TIME_INTERVAL_UNIT = 1000;

    private static final String TAG = "SimLoginNeedVerifyActivity";

    private static final String KEY_SEQUENCE = "key.sequence.list";

    /**
     * 需要倒计时的对象们
     */
    private List<SimLoginNeedVerifyActivity.CountDownDesc> sequenceList = Collections.synchronizedList(new ArrayList<SimLoginNeedVerifyActivity.CountDownDesc>());

    /**
     * 计时器
     */
    private CountDownTimer mCountDownTimer;

    /**
     * 发送验证码
     *
     * @param desc 发送验证码的描述实体对象
     */
    public void sendVerifyCode(SimLoginNeedVerifyActivity.CountDownDesc desc) {
        if (sequenceList.contains(desc)) {
            sequenceList.remove(desc);
        }
        sequenceList.add(desc);
        startCountDownTimerIfNeeded();
    }

    /**
     * 发送验证码失败，默认情况下，发送验证码失败，用户可以不用等待倒计时完成就可以发送
     *
     * @param desc 发送验证码的描述对象
     */
    public void sendVerifyCodeFailure(SimLoginNeedVerifyActivity.CountDownDesc desc) {
        int index = sequenceList.indexOf(desc);
        if (index >= 0) {
            SimLoginNeedVerifyActivity.CountDownDesc sequence = sequenceList.get(index);
            sequence.countDownRemainTime = 0;
        } else {
            desc.countDownRemainTime = 0;
            sequenceList.add(desc);
        }
        startCountDownTimerIfNeeded();
    }


    /**
     * 启动倒计时
     */
    protected void startCountDownTimerIfNeeded() {
        if (mCountDownTimer != null) {
            mCountDownTimer.cancel();
            mCountDownTimer = null;
        }

        long maxRemainTime = 0;
        final int len = sequenceList.size();
        List<Integer> deadObjects = new ArrayList<>();

        for (int i = 0; i < len; i++) {
            SimLoginNeedVerifyActivity.CountDownDesc sequence = sequenceList.get(i);
            if (sequence != null) {
                if (sequence.countDownRemainTime > 0) {
                    maxRemainTime = Math.max(sequence.countDownRemainTime, maxRemainTime);
                } else {
                    deadObjects.add(i);
                    updateCountDownDisplay(sequence);
                }
            } else {
                deadObjects.add(i);
            }
        }

        for (int i = 0; i < deadObjects.size(); i++) {
            sequenceList.remove((int) deadObjects.get(i));
        }

        if (maxRemainTime > 0) {
            mCountDownTimer = new CountDownTimer(maxRemainTime, MIN_TIME_INTERVAL_UNIT) {

                @Override
                public void onTick(long millisUntilFinished) {
                    Iterator<SimLoginNeedVerifyActivity.CountDownDesc> it = sequenceList.iterator();
                    while (it.hasNext()) {
                        SimLoginNeedVerifyActivity.CountDownDesc sequence = it.next();
                        sequence.countDownRemainTime -= MIN_TIME_INTERVAL_UNIT;
                        if (sequence.countDownRemainTime <= 0) {
                            sequence.countDownRemainTime = 0;
                            it.remove();
                        }
                        updateCountDownDisplay(sequence);
                    }
                }

                @Override
                public void onFinish() {
                    onTick(MIN_TIME_INTERVAL_UNIT);
                    if (Config.DEBUG) {
                        ALog.d(TAG, "onFinish -> " + sequenceList.toString());
                    }
                }
            };
            mCountDownTimer.start();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mCountDownTimer != null) {
            mCountDownTimer.cancel();
            mCountDownTimer = null;
        }
    }

    /**
     * 更新显示器
     * 子类重写这个方法，以获取更好的效果
     *
     * @param sequence 需要更新的对象
     */
    protected void updateCountDownDisplay(SimLoginNeedVerifyActivity.CountDownDesc sequence) {
        if (Config.DEBUG) {
            ALog.d(TAG, "UpdateCountDownDisplay caller -> " + this);
        }
        View v = findViewById(sequence.viewId);
        if (v == null) {
            if (Config.DEBUG) {
                ALog.d(TAG, "尝试更新显示器，但是根据你指定的视图ID " + sequence.viewId + " 没有找到任何匹配的视图");
            }
        } else {
            if (v instanceof TextView) {
                if (Config.DEBUG) {
                    ALog.d(TAG, "Update display object " + sequence);
                }
                if (sequence.countDownRemainTime >= MIN_TIME_INTERVAL_UNIT) {
                    if (v.isEnabled()) v.setEnabled(false);
                    ((TextView) v).setText(String.format(getString(R.string.count_down), sequence.countDownRemainTime / 1000));
                } else {
                    if (!v.isEnabled()) v.setEnabled(true);
                    ((TextView) v).setText(R.string.send_verify_code);
                }
            } else {
                if (Config.DEBUG) {
                    ALog.d(TAG, "尝试更新显示器，但是默认的处理方法不支持你指定的View" + v.getClass().getSimpleName());
                }
            }
        }

    }

    @Override
    protected void onSaveInstanceState(@NonNull Bundle outState) {
        super.onSaveInstanceState(outState);
        ArrayList<SimLoginNeedVerifyActivity.CountDownDesc> dest = new ArrayList<>();
        for (SimLoginNeedVerifyActivity.CountDownDesc d : sequenceList) dest.add(d);
        outState.putParcelableArrayList(KEY_SEQUENCE, dest);
    }

    @Override
    public void restoreInstanceOnCreateBefore(@NonNull Bundle savedInstance) {
        ArrayList<SimLoginNeedVerifyActivity.CountDownDesc> list = savedInstance.getParcelableArrayList(KEY_SEQUENCE);
        if (list != null) {
            sequenceList.addAll(list);
            startCountDownTimerIfNeeded();
        }
    }

    /**
     * 倒计时描述实体
     */
    public static class CountDownDesc implements Parcelable {
        public static final Creator<SimLoginNeedVerifyActivity.CountDownDesc> CREATOR = new Creator<SimLoginNeedVerifyActivity.CountDownDesc>() {
            public SimLoginNeedVerifyActivity.CountDownDesc createFromParcel(Parcel source) {
                return new SimLoginNeedVerifyActivity.CountDownDesc(source);
            }

            public SimLoginNeedVerifyActivity.CountDownDesc[] newArray(int size) {
                return new SimLoginNeedVerifyActivity.CountDownDesc[size];
            }
        };
        /**
         * 资源id，一般情况就是发送按钮
         */
        int viewId;
        /**
         * 倒计时的总时间
         */
        long countDownCountTime;
        /**
         * 编号，序号
         */
        int sequenceNumber;
        /**
         * 倒计时还剩余多少时间
         */
        long countDownRemainTime;

        public CountDownDesc() {
        }

        public CountDownDesc(int viewId, long countDownCountTime, int sequenceNumber) {
            this.viewId = viewId;
            this.countDownCountTime = countDownCountTime;
            this.sequenceNumber = sequenceNumber;
            this.countDownRemainTime = countDownCountTime;
        }

        protected CountDownDesc(Parcel in) {
            this.viewId = in.readInt();
            this.countDownCountTime = in.readLong();
            this.sequenceNumber = in.readInt();
            this.countDownRemainTime = in.readLong();
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            SimLoginNeedVerifyActivity.CountDownDesc that = (SimLoginNeedVerifyActivity.CountDownDesc) o;

            return sequenceNumber == that.sequenceNumber;

        }

        @Override
        public int hashCode() {
            return sequenceNumber;
        }

        @Override
        public int describeContents() {
            return 0;
        }

        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeInt(this.viewId);
            dest.writeLong(this.countDownCountTime);
            dest.writeInt(this.sequenceNumber);
            dest.writeLong(this.countDownRemainTime);
        }

        /**
         * 重置，重置并不代表清楚数据，在这里只是将剩余时间设置为总共的倒计时时长
         *
         * @return 重置后的对象
         */
        public SimLoginNeedVerifyActivity.CountDownDesc reset() {
            countDownRemainTime = countDownCountTime;
            return this;
        }

        @Override
        public String toString() {
            return "CountDownDesc{" +
                    "viewId=" + viewId +
                    ", countDownCountTime=" + countDownCountTime +
                    ", sequenceNumber=" + sequenceNumber +
                    ", countDownRemainTime=" + countDownRemainTime +
                    '}';
        }
    }
    
}
